import EventSystem from "./EventSystem";
import GameNet from "../gamenet/GameNet";
import { BaseProtocolStruct, ProtocolPool } from "../gamenet/protobufs/base/BaseProtocol";
import LocalStore from "../utils/LocalStore";

abstract class BaseView extends EventSystem { }
abstract class BaseCtrl extends EventSystem { }
abstract class BaseData extends EventSystem { }
abstract class BaseEntity extends EventSystem { }
abstract class BaseVO extends EventSystem { }

function getClassName(obj: any){
    let str = (obj.prototype ? obj.prototype.constructor : obj.constructor).toString();
    return str.match(/function\s(\w*)/)[1];
}
export namespace MVCS {
    export abstract class View extends BaseView {
        viewHandler = {
            path: ``,
            closeDelete: true,
            closeHandler: (path: string, isDelete?: boolean) => { },
        }
        /** 引擎版本生命周期,不要直接调用 */
        start(){this.onStart();}
        update(dt: number){this.onUpdate(dt);}

        /** 初始化 */
        init(data?: any) { }

        /** 生命周期 */
        onFlush() { }
        onClose() {
            if (this.viewHandler.closeHandler)
                this.viewHandler.closeHandler(this.viewHandler.path, this.viewHandler.closeDelete);
        }
        onLoad() { }
        onStart(){}
        onUpdate(dt: number){}

        /** 关闭时是否销毁面板 */
        setCloseDelete(bool: boolean) {
            this.viewHandler.closeDelete = bool;
        }
    }

    export abstract class Ctrl extends BaseCtrl {
        /** 协议注册 */
        rigisterProtocol(protocol: typeof BaseProtocolStruct, funName?: string){
            let msgType = ProtocolPool.instance.rigister(protocol);
            if(msgType < 0) return;
            if(!this[funName]){
                // console.error(`fun not exit! className: ${protocol.name} funName: ${funName}`);
                return;
            }

            GameNet.instance.rigiserMsgOperate(msgType, this[funName].bind(this));
        }
        /** 注册事件监听 */
        rigisterEventListener(){}
    }

    export abstract class Data extends BaseData {
        static userData: any = {};
        protected _vo: VO = null;

        constructor(){
            super();
            let data = Data.userData[getClassName(this)] || {};
            setTimeout(() => {
                if(this._vo){
                    for(let key in data){
                        this._vo[key] = data[key];
                    }
                }
            }, 0);
        }

        /** 读取数据需要在实例化前调用 */
        static readData(){
            let dataStr = LocalStore.getItem("userData");
            Data.userData = dataStr ? JSON.parse(dataStr) : {};
        }

        saveData(): Promise<any> {
            return new Promise(() => {
                let data = {};
                if(this._vo){
                    let saveField = this._vo.saveField();
                    for(let i = 0; i < saveField.length; ++i){
                        let key = saveField[i];
                        let value = this._vo[key];
                        data[key] = value;
                    }
                }
                let cname = getClassName(this);
                Data.userData[cname] = data;
                LocalStore.setItem("userData", JSON.stringify(Data.userData));
            });
        }
        saveLocalData(){}
    }

    export abstract class Entity extends BaseEntity {

    }

    export abstract class VO extends BaseVO {
        saveField(){
            return [];
        }
    }
}